<?php

namespace app\admin\model\order;

use think\facade\Db;
use think\facade\Log;
use app\common\model\Export;

class OilCard
{
    private $table = 'oil_card_order';
    private $error = '';

    /**
     * 列表.
     */
    public function getList($params)
    {
        $where = [];
        $where[] = ['status', '=', 2];
        $agentName = $params['agent_name'] ?? '';
        if ($agentName) {
            $agentId = Db::name('agent')
                ->where('username|company_name', 'like', '%'.$agentName.'%')
                ->column('id');
            if ($agentId) {
                $where[] = ['agent_id', 'in', $agentId];
            } else {
                $where[] = ['agent_id', '=', -1];
            }
        }
        $username = trim($params['username'] ?? '');
        if ($username) {
            $where[] = ['username', 'like', '%'.$username.'%'];
        }
        $orderId = trim($params['order_id'] ?? '');
        if ($orderId) {
            $where[] = ['sub_order_id|out_order_id|supplier_order_no', '=', $orderId];
        }
        if (!empty($params['supplier_id'])) {
            $where[] = ['supplier_id', '=', $params['supplier_id']];
        }
        if (!empty($params['card_type'])) {
            $where[] = ['card_type', '=', $params['card_type']];
        }
        if (!empty($params['order_type'])) {
            $where[] = ['order_type', '=', $params['order_type']];
        }
        if (!empty($params['supplier_status'])) {
            if (in_array($params['supplier_status'], [3, 4])) {
                $where[] = ['supplier_status', '=', $params['supplier_status']];
            } else {
                $where[] = ['supplier_status', 'in', [1, 2]];
            }
        }
        if (!empty($params['refund_status'])) {
            if (2 == $params['refund_status']) {
                $where[] = ['supplier_status', '=', 4];
            }
            $where[] = ['refund_status', '=', $params['refund_status']];
        }
        $createdDate = $params['created_at'] ?? [];
        if (is_array($createdDate) && !empty($createdDate[0]) && $createdDate[1]) {
            $where[] = ['created_at', 'between time', [$createdDate[0], $createdDate[1].' 23:59:59']];
        }
        $finishTime = $params['finish_time'] ?? [];
        if (is_array($finishTime) && !empty($finishTime[0]) && $finishTime[1]) {
            $where[] = ['finish_time', 'between time', [strtotime($finishTime[0]), strtotime($finishTime[1].' 23:59:59')]];
        }
        // 供应商
        $supplierList = Db::name('base_supplier')
            ->field('id, name')
            ->where('serv_type', PRODUCT_OILCARD_SERV)
            ->whereNull('deleted_at')
            ->order('id desc')
            ->select()
            ->toArray();
        $supplier = array_column($supplierList, 'name', 'id');

        $paginate = [
            'page' => $params['page'] ?? 1,
            'list_rows' => $params['list_rows'] ?? 10,
        ];
        $db = Db::name($this->table)
            ->where($where)
            ->order('id desc');
        if (isset($params['is_export']) && 1 == $params['is_export']) {
            // 返回导出excel 需要的数据
            $list = $db->order('id desc')->select()->toArray();
            $agentIds = array_column($list, 'agent_id');
        } else {
            $list = $db->order('id desc')->paginate($paginate)->toArray();
            $agentIds = array_column($list['data'], 'agent_id');
        }
        // 代理商
        if ($agentIds) {
            $agent = Db::name('agent')
                ->whereIn('id', $agentIds)
                ->order('username asc')
                ->column('username, company_name', 'id');
        }

        // 导出 excel
        if (!empty($params['is_export'])) {
            $res = [];
            $title = ['系统订单号', '持卡人姓名', '油卡卡号', '油卡类型', '充值类型', '充值金额', '成本价',
            '结算价', '平台利润', '代理商利润', '订单状态', '下单时间', '完成时间', '代理商用户名', '代理商公司名称', '供应商', '备注'];
            $statusMap = [
                -1 => '代理商余额不足',
                1 => '充值中',
                2 => '充值中',
                3 => '充值成功',
                4 => '充值失败',
            ];
            foreach ($list as $v) {
                if ($v['finish_time']) {
                    $v['finish_time'] = date('Y-m-d H:i:s', $v['finish_time']);
                } else {
                    $v['finish_time'] = '';
                }
                $res[] = [
                    $v['order_id']."\t",
                    $v['username'],
                    $v['card_no'],
                    $v['card_type'] == 1 ? '中石油' : '中石化',
                    $v['order_type'] == 1 ? '慢充' : '快充',
                    fen2yuan($v['amount']).'',
                    fen2yuan($v['supplier_price']).'',
                    fen2yuan($v['settle_price']).'',
                    fen2yuan($v['platform_profit']).'',
                    fen2yuan($v['profit']).'',
                    $statusMap[$v['supplier_status']] ?? '充值中',
                    $v['created_at'],
                    $v['finish_time'],
                    $agent[$v['agent_id']]['username'] ?? '',
                    $agent[$v['agent_id']]['company_name'] ?? '',
                    $supplier[$v['supplier_id']] ?? '',
                    $v['remark'],
                ];
            }
            unset($list);
            $export = new Export;
            $name = '油卡订单';
            return $export->downloadExcel($title, $res, $name);
        }

        foreach ($list['data'] as $k => $v) {
            $list['data'][$k]['agent_name'] = $agent[$v['agent_id']]['username'] ?? '';
            $list['data'][$k]['company_name'] = $agent[$v['agent_id']]['company_name'] ?? '';
            $list['data'][$k]['supplier_name'] = $supplier[$v['supplier_id']] ?? '--';
            if ($v['finish_time']) {
                $list['data'][$k]['finish_time'] = date('Y-m-d H:i:s', $v['finish_time']);
            }
        }
        $list['supplierList'] = $supplierList;

        return success('操作成功', $list);
    }

    /**
     * 退款.
     */
    public function refund($id)
    {
        $order = Db::name($this->table)
            ->where('id', $id)
            ->find();
        if (empty($order)) {
            $this->error = '订单不存在';

            return false;
        }

        if (2 != $order['status']) {
            $this->error = '该订单尚未支付';

            return false;
        }
        if (4 != $order['supplier_status']) {
            $this->error = '充值失败的订单才能退款【'.$order['supplier_status'].'】';

            return false;
        }
        if (2 != $order['refund_status']) {
            $this->error = '退款状态有误【'.$order['refund_status'].'】';

            return false;
        }
        $res = Db::name($this->table)
            ->where('id', $order['id'])
            ->where('refund_status', 2)
            ->update([
                'refund_status' => 4, // 退款中
            ]);
        if (!$res) {
            $this->error = '退款状态有误' . __LINE__;
            return false;
        }

        $refundFee = 0;
        $refundSettleFee = $order['settle_price'];
        if ($order['order_from'] == ORDER_FROM_H5
        || ($order['order_from'] == ORDER_FROM_API && $order['settle_type'] == SETTLE_TYPE_PROFIT)
        ) {
            // H5 过来的订单或者api返佣的，才有在线支付
            $payLog = Db::name('oil_card_pay_log')
                ->where('order_id', $order['order_id'])
                ->where('status', 2)
                ->find();
            if (empty($payLog)) {
                $this->error = '支付记录不存在';

                return false;
            }

            $refundFee = $payLog['real_pay_price'];
            $refundSettleFee = $payLog['settle_price'];

            $payLog['refund_fee'] = $refundFee;
            $res = $this->wxpayRefund($payLog);
            if (false === $res) {
                return false;
            }
        }

        Db::startTrans();
        try {
            $res = Db::name($this->table)
                ->where('id', $order['id'])
                ->where('refund_status', 4)
                ->update([
                    'refund_status' => 3,
                ]);
            if (!$res) {
                Db::rollback();

                $this->error = '退款失败：重复退款';
                return false;
            }

            // 预付的，要给代理商退钱
            if (SETTLE_TYPE_PREPAY == $order['settle_type']) {
                $balance = Db::name('agent')
                    ->where('id', $order['agent_id'])
                    ->value('balance');
                $newBalance = $balance + $refundSettleFee;
                Db::name('agent')
                    ->where('id', $order['agent_id'])
                    ->inc('balance', $refundSettleFee)
                    ->update([
                        'balance_last_updated_at' => date('Y-m-d H:i:s'),
                    ]);
                Db::name('agent_balance_log')
                    ->insert([
                        'agent_id' => $order['agent_id'],
                        'type' => BALANCE_OILCARD_REFUND,
                        'amount' => $refundSettleFee,
                        'old_balance' => $balance,
                        'new_balance' => $newBalance,
                        'remark' => '油卡充值失败退款：'.fen2yuan($refundSettleFee).' 元。订单号：'.$order['sub_order_id'],
                        'quote_id' => $order['id'],
                        'trade_no' => $order['sub_order_id'],
                    ]);
            }
            if ($order['order_from'] == ORDER_FROM_H5
            || ($order['order_from'] == ORDER_FROM_API && $order['settle_type'] == SETTLE_TYPE_PROFIT)
            ) {
                Db::name('oil_card_pay_log')
                    ->where('id', $payLog['id'])
                    ->inc('refund_amount', $refundFee)
                    ->inc('refund_settle_amount', $refundSettleFee)
                    ->update();
            }

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();

            $this->error = '退款失败：'.$e->getMessage();

            return false;
        }

        return true;
    }

    /**
     * 微信退款.
     */
    private function wxpayRefund($payLog)
    {
        try {
            if (SETTLE_TYPE_PREPAY == $payLog['settle_type']) {
                $wxpay = new \app\common\model\Wxpay($payLog['agent_id']);
            } else {
                $type = 'wechat';
                if ('MWEB' == $payLog['trade_type']) {
                    $type = 'wechat_mweb';
                }
                $wxpay = new \app\common\model\Wxpay(0, $type);
            }
            $data = [
                'transactionId' => $payLog['trade_no'],
                'refundNumber' => $payLog['order_id'],
                'totalFee' => $payLog['real_pay_price'],
                'refundFee' => $payLog['refund_fee'],
                'desc' => '充值失败退款',
            ];
            $res = $wxpay->refund($data);
        } catch (\Exception $e) {
            $this->error = $e->getMessage();

            return false;
        }

        if (!isset($res['result_code']) || 'SUCCESS' != $res['result_code']) {
            $this->error = '退款失败：'.json_encode($res, JSON_UNESCAPED_UNICODE);

            return false;
        }

        return true;
    }

    public function getError()
    {
        return $this->error;
    }
}
